using System;
using System.Runtime.Serialization;
using System.Web.Mvc;
using System.Web.Routing;
using LCA.Community.Web.Controllers;
using System.Text;
using System.Resources;

namespace LCA.Community.Web.Filters
{
    /// <summary>
    /// Filter for handling errors and exceptions.
    /// </summary>
    [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
    public class ErrorFilter : ActionFilterAttribute
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="ErrorFilter"/> class.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="errorResource">The message.</param>
        /// <param name="order">The order.</param>
        public ErrorFilter(Type type, string errorResource, int order)
            : base()
        {
            base.Order = order;
            ExceptionType = type;
            ErrorResource = errorResource;
        }

        /// <summary>
        /// Called by the MVC framework after the action method executes.
        /// </summary>
        /// <param name="filterContext">The filter context.</param>
        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            if (filterContext.Exception != null && filterContext.Exception.GetType().Equals(ExceptionType))
            {
                if (filterContext.HttpContext.Request.IsAjaxRequest())
                {
                    var message = Resources.Errors.ResourceManager.GetString(ErrorResource);
                    filterContext.Result = new ContentResult() { ContentType = "text/plain", Content = string.Concat("<div>\n", message, "\n</div>"), ContentEncoding = Encoding.UTF8 };
                }
                else
                {
                    filterContext.HttpContext.Response.ClearContent();
                    filterContext.HttpContext.Response.Redirect(new UrlHelper(filterContext.RequestContext).Action("Index", "Error", new { ErrorResource = ErrorResource }));
                }

                filterContext.ExceptionHandled = true;
            }
        }

        /// <summary>
        /// Called by the MVC framework after the action result executes.
        /// </summary>
        /// <param name="filterContext">The filter context.</param>
        public override void OnResultExecuted(ResultExecutedContext filterContext)
        {
            if (filterContext.Exception != null
               &&
               filterContext.Exception.InnerException != null
               &&
               (ExceptionType.IsAssignableFrom(filterContext.Exception.InnerException.GetType())
                || ExceptionType.Equals(filterContext.Exception.InnerException)))
            {
                if (filterContext.HttpContext.Request.IsAjaxRequest())
                {
                    var message = Resources.Errors.ResourceManager.GetString(ErrorResource);

                    filterContext.Result = new ContentResult()
                                               {
                                                   ContentType = "text/plain",
                                                   Content = string.Concat("<div>\n", message, "\n</div>"),
                                                   ContentEncoding = Encoding.UTF8,
                                               };
                }
                else
                {
                    filterContext.HttpContext.Response.Clear();
                    filterContext.HttpContext.Response.Redirect(new UrlHelper(filterContext.RequestContext).Action("Index", "Error", new { errorResource = ErrorResource }));
                    filterContext.ExceptionHandled = true;
                }
            }
        }

        #region Properties
        public string ErrorResource { get; set; }
        public Type ExceptionType { get; set; }
        public int Order { get; set; }
        #endregion
    }
}